using Microsoft.EntityFrameworkCore;
using System.Reflection;
using System.IO;
using MediatR;
using WeatherMcpServer.Data.Repositories;
using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;
using Microsoft.EntityFrameworkCore.Infrastructure;
using WeatherMcpServer.Services.Weather;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    if (File.Exists(xmlPath))
    {
        c.IncludeXmlComments(xmlPath, includeControllerXmlComments: true);
    }
});

builder.Services.AddMcpServer().WithHttpTransport();

// 注册 MCP 服务并扫描程序集工具
builder.Services
.AddMcpServer()
.WithToolsFromAssembly(typeof(Program).Assembly);
// 注册 HttpClientFactory，让依赖注入能提供 IHttpClientFactory
builder.Services.AddHttpClient();

// 内存缓存（供工具使用）
builder.Services.AddMemoryCache();

// CORS: 允许前端本地开发访问
builder.Services.AddCors(options =>
{
    options.AddPolicy("mcpvue", policy =>
        policy
            .AllowAnyHeader()
            .AllowAnyMethod()
            .SetIsOriginAllowed(_ => true) // 开发阶段放开所有来源
            .AllowCredentials());
});

// 简单的全局限流：固定窗口，每个 IP 每分钟 60 次
builder.Services.AddRateLimiter(options =>
{
    options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(context =>
        RateLimitPartition.GetFixedWindowLimiter(
            partitionKey: context.Connection.RemoteIpAddress?.ToString() ?? "unknown",
            factory: _ => new FixedWindowRateLimiterOptions
            {
                PermitLimit = 60,
                Window = TimeSpan.FromMinutes(1),
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit = 0
            }));
});

// EF Core DbContext
builder.Services.AddDbContext<WeatherMcpServer.Data.WeatherDbContext>(options =>
{
    var cs = builder.Configuration.GetConnectionString("WeatherDb");
    if (!string.IsNullOrWhiteSpace(cs))
    {
        options.UseMySql(cs, ServerVersion.AutoDetect(cs)); // MySQL 5.7
    }
});

// MediatR
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));

// Repositories
builder.Services.AddScoped<IWeatherAlertRepository, EfWeatherAlertRepository>();
builder.Services.AddScoped<IWeatherRuleRepository, EfWeatherRuleRepository>();

// Weather Providers (multi-source ready)
builder.Services.AddSingleton<IWeatherProvider, AmapWeatherProvider>();
builder.Services.AddSingleton<IWeatherProvider, OpenMeteoWeatherProvider>();

var app = builder.Build();

// 诊断：提示 AMAP_KEY 是否配置
var amapKey = (Environment.GetEnvironmentVariable("AMAP_KEY") ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(amapKey))
{
    app.Logger.LogWarning("AMAP_KEY is NOT set. AMap APIs will fail.");
}
else
{
    app.Logger.LogInformation("AMAP_KEY is configured.");
}

// 确保数据库可用：有迁移则执行迁移；否则首次创建
using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<WeatherMcpServer.Data.WeatherDbContext>();
    try
    {
        var hasMigrations = db.Database.GetMigrations().Any();
        if (hasMigrations)
        {
            db.Database.Migrate();
        }
        else
        {
            db.Database.EnsureCreated();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Database init failed: {ex}");
    }
}

app.MapMcp(); // 注册 SSE 端点

// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI();
//}

app.UseRateLimiter();
app.UseAuthorization();

// 启用 CORS（在 MapControllers 之前）
app.UseCors("mcpvue");

app.MapControllers();

app.Run();
